/* 
 * File:   CArray.h
 * Author: kisme
 *
 * Created on 18 March 2010, 4:35 PM
 */

#ifndef _ARRAY_H
#define	_ARRAY_H

// exit..
#include <stdlib.h>
// errno
#include <errno.h>
// printf..
#include <stdio.h>

enum ARRAY_RETURN_STATE
{
    ARRAY_DEFAULT_SUCCESS = 1
};

/**
 * IPC module
 */
struct IPC_Conf
{
    // what kind of IPC use for this epoll
    int m_nIPC_mode;
    // default value
    IPC_Conf()
    {
        m_nIPC_mode = 0;
    }
};

/**
 * this can's configure struct
 */
struct Array_Conf
{
    int m_nArray_Size;
    int m_nPosition;
    
    Array_Conf()
    {
        m_nArray_Size = 1000;
        m_nPosition = 0;
    }
};

/**
 * Array's node
 */
template <typename T>
struct NODE
{
    int m_nNodeId;
    int m_nIsUsed; // 0 for not use, 1 for has be used.
    T m_tData;
    int m_nNodeType;
    NODE* m_pNext;
};

template <typename T>
class Array
{
private:
    /**
     * this Array-Class's configure struct
     */
    struct Array_Conf m_sConf;
    /**
     * this Array-Class's can
     */
    struct NODE<T>* m_aNodeArray;
public:
    /**
     * add one node into array
     */
    int add(T a_tData);
    /**
     * pick one node's data from this array by index
     */
    T* getByIndex(int a_nNum);
    /**
     * return array's size
     */
    int size();

    Array<T>();
    Array<T>(struct Array_Conf a_sConf);
};



template<typename T>
Array<T>::Array()
{
    m_aNodeArray = new NODE<T>[m_sConf.m_nArray_Size];
    int _i = 0;
    while(_i < m_sConf.m_nArray_Size)
    {
        m_aNodeArray[_i].m_nIsUsed = 0;
        m_aNodeArray[_i].m_nNodeId = _i;
        _i++;
    }
}

template<typename T>
Array<T>::Array(struct Array_Conf a_sConf)
{
    this->m_sConf = a_sConf;
    m_aNodeArray = new NODE<T>[m_sConf.m_nArray_Size];
    int _i = 0;
    while(_i < m_sConf.m_nArray_Size)
    {
        m_aNodeArray[_i].m_nIsUsed = 0;
        m_aNodeArray[_i].m_nNodeId = _i;
        _i++;
    }
}

template<typename T>
int Array<T>::add(T a_tData)
{
    m_aNodeArray[m_sConf.m_nPosition].m_nIsUsed = 1;
    m_aNodeArray[m_sConf.m_nPosition].m_tData = a_tData;
    
    m_sConf.m_nPosition++;

    return 0;
}

template<typename T>
T* Array<T>::getByIndex(int a_nNum)
{
    if(a_nNum >= m_sConf.m_nArray_Size)
    {
        // 未触发错误，errno并没有被赋什么值
        fprintf(stderr, "Too large for the Array. \n");
        exit(1);
    }
    else if(a_nNum < 0)
    {
        fprintf(stderr, "Too small for the Array. \n");
        exit(1);
    }
    else
    {
        return &(m_aNodeArray[a_nNum].m_tData);
    }
}

template<typename T>
int Array<T>::size()
{
    int _nSize = 0;
    while(m_aNodeArray[_nSize].m_nIsUsed != 0)
    {
        _nSize++;
    }
    return _nSize;
}

#endif	/* _ARRAY_H */